package com.kx.yooli.kx.wechat.service.mail;
import com.kx.yooli.kx.wechat.constant.Constants;
import com.kx.yooli.kx.wechat.constant.LoanStatusConstant;
import com.kx.yooli.kx.wechat.entity.bill.BillEntity;
import com.kx.yooli.kx.wechat.entity.nplm.LoanContractEntity;
import com.kx.yooli.kx.wechat.mapper.bill.BillMapper;
import com.kx.yooli.kx.wechat.mapper.nplm.ILoanContractMapper;
import com.kx.yooli.kx.wechat.mapper.user.UserInfoMapper;
import com.kx.yooli.kx.wechat.po.result.AjaxResult;
import com.kx.yooli.kx.wechat.po.user.UserInfo;
import com.kx.yooli.kx.wechat.service.IEmailService;
import com.kx.yooli.kx.wechat.utils.date.DateCustomUtils;
import com.kx.yooli.kx.wechat.utils.security.MD5Util;
import com.lowagie.text.*;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
import jakarta.annotation.Resource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.*;

/**
 * @author john_sqwen-childe.wen
 * date 2024/6/13
 * PROJECT_NAME wechat
 * description create EmailServiceImpl by john_sqwen
 * and  value is
 */
@Service
public class EmailServiceImpl implements IEmailService {
    private final Logger log = LoggerFactory.getLogger(EmailServiceImpl.class);
    @Resource
    private JavaMailSender mailSender;
    private final UserInfoMapper userInfoMapper;
    private final BillMapper billMapper;
    private final ILoanContractMapper iLoanContractMapper;
    /**
     * 发送方
     */
    @Value("${spring.mail.username}")
    private String from;

    public EmailServiceImpl(UserInfoMapper userInfoMapper, BillMapper billMapper, ILoanContractMapper iLoanContractMapper) {
        this.userInfoMapper = userInfoMapper;
        this.billMapper = billMapper;
        this.iLoanContractMapper = iLoanContractMapper;
    }

    @Override
    public void checkMail(String to, String subject, String text) {
        if(StringUtils.isEmpty(to)){
            throw new RuntimeException("邮件收信人不能为空");
        }
        if(StringUtils.isEmpty(subject)){
            throw new RuntimeException("邮件主题不能为空");
        }
        if(StringUtils.isEmpty(text)){
            throw new RuntimeException("邮件内容不能为空");
        }
    }

    @Override
    public void sendTextMailMessage(String to, String subject, String text) {
        checkMail(to,subject,text);
        //true 代表支持复杂的类型
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mailSender.createMimeMessage(),true);
            //SimpleMailMessage message = new SimpleMailMessage();
            mimeMessageHelper.setFrom(from);
            mimeMessageHelper.setTo(to);
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(text);
            mailSender.send(mimeMessageHelper.getMimeMessage());
            log.info("mail send success ");
        } catch (MessagingException e) {
            log.info("send mail fail cause {}",e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendHtmlMail(String to, String subject, String content) throws MessagingException {
        checkMail(to,subject,content);
        MimeMessage message = mailSender.createMimeMessage();
        //true表示需要创建一个multipart message
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);
        mailSender.send(message);
    }

    @Override
    public void sendAttachmentsMail(String to, String subject, String content, String files) throws MessagingException {
        checkMail(to,subject,content);
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        //true 代表支持复杂的类型
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);
        FileSystemResource file = null;
        //添加附件
        if(!files.isEmpty()) {
            file = new FileSystemResource(files);
            helper.addAttachment("结清证明.pdf", file);
        }
        log.info("进入邮件发送最后阶段to：{}，subject：{}",to,subject);
        mailSender.send(mimeMessage);
    }

    @Override
    public String sendAttachmentsMail(String mobile,String mail) throws MessagingException {
        log.info("开始发送邮件mobile:{},mail:{}",mobile,mail);
        String result="Ok 发送成功";
        if(!MD5Util.checkMailStyle(mail)){
            AjaxResult.error("邮箱不正确，请重新输入");
            result="邮箱不正确，请重新输入";
            throw new RuntimeException("邮箱不正确，请重新输入");
        }
        if(mobile.isBlank()){
            AjaxResult.error("参数手机号为空");
            result="参数手机号为空";
            throw new RuntimeException();
        }
        if (mail.isBlank()){
            AjaxResult.error("参数邮箱为空");
            result="参数邮箱为空";
            throw new RuntimeException();
        }
        UserInfo userInfo = userInfoMapper.selectCertNoByMobile(mobile);
        log.info("邮箱发送查询用户信息:{}",userInfo);
        if(null == userInfo ){
            AjaxResult.error("未查到相关数据！");
            result="未查到相关数据";
            throw new RuntimeException();
        }
        //根据用户表中的身份证号去查询 repayment 表中的 合同号
        if(userInfo.getCertNo().isBlank()){
            AjaxResult.error("未查询到相关数据");
            result="未查询到相关数据";
            throw new RuntimeException();
        }
        BillEntity billEntity = billMapper.selectLoanByCertNo(userInfo.getCertNo());
        log.info("邮件发送查询用户对应的合同信息:{}",billEntity);
        if(null != billEntity){
            if(!billEntity.getLoanNo().isBlank()){
                //如果 查出来的实体不为空，刚进行各数据库的数据查询
                //1 查快信贷后，就是nplm 数据库和其它数据库
                LoanContractEntity loanContractEntity = iLoanContractMapper.selectLoanInfoByNo(billEntity.getLoanNo());
                //如果查询到数据并且正常返回， 查询 其它的库有无未结清的合同，如果 有则不发送结清证明，如果 没有则发送
                if(null != loanContractEntity){
                    if(!loanContractEntity.getContractStatus().isBlank()){
                        if(LoanStatusConstant.CONTRACT_STATUS_NOMAL_PAYED.equals(loanContractEntity.getContractStatus())
                                || LoanStatusConstant.CONTRACT_STATUS_NORMAL_PRE_PAYED.equals(loanContractEntity.getContractStatus())
                                || LoanStatusConstant.CONTRACT_STATUS_CREDIT_PAYED.equals(loanContractEntity.getContractStatus())
                                || LoanStatusConstant.CONTRACT_STATUS_CREDIT_PRE_PAYED.equals(loanContractEntity.getContractStatus())
                                || LoanStatusConstant.CONTRACT_STATUS_RETURN_APPLY.equals(loanContractEntity.getContractStatus()))
                        {
                            configPdf( userInfo.getCertNo(), loanContractEntity.getClearTime(),loanContractEntity.getLoanNo(),loanContractEntity.getCustName(),loanContractEntity.getSubChannel());
                            String path =  Constants.PDF_URL+userInfo.getCertNo()+".pdf";
                            log.info("邮件发送结清证明pdf path:{}",path);
                            sendAttachmentsMail(mail,"结清证明","您好！ 附件为结清证明，请注意查收，请知悉。祝：生活愉快！",path);
                        }
                    }
                    else {
                        AjaxResult.error("您有未结清的合同，请结清后再进行结清证明申请~！");
                        result="您有未结清的合同，请结清后再进行结清证明申请~！";
                    }
                }
            }
        }
        return result;
    }
    private void configPdf( String certNo,  Date clearDate,String loanNo,String custName,String subChannel){
        if(subChannel.isBlank()){
            throw  new RuntimeException("子渠道未正常获取！");
        }
        //创建一个文档对象
        Document doc = new Document(PageSize.A4);
        if(LoanStatusConstant.SUB_CHANNEL_031.equals(subChannel)
                || LoanStatusConstant.SUB_CHANNEL_022.equals(subChannel)
                || LoanStatusConstant.SUB_CHANNEL_023.equals(subChannel)
                || LoanStatusConstant.SUB_CHANNEL_024.equals(subChannel)
                || LoanStatusConstant.SUB_CHANNEL_025.equals(subChannel))
        {
            //处理柠檬的合同结清证明
            addPdf(doc,"深圳柠檬金融信息服务有限公司",certNo,custName,clearDate,loanNo);
        } else if(LoanStatusConstant.SUB_CHANNEL_006.equals(subChannel)){
            addPdf(doc,"信产利卡科技有限公司",certNo,custName,clearDate,loanNo);
        }else {
            addPdf(doc,"深圳普惠快信金融服务有限公司",certNo,custName,clearDate,loanNo);
        }

    }
    private void addPdf(Document doc ,  String companyName, String certNo, String custName, Date clearDate, String loanNo){
        try {
            PdfWriter.getInstance(doc, new FileOutputStream(Constants.PDF_URL +certNo+".pdf"));
            // 设置中文字体
            BaseFont bfChinese = BaseFont.createFont(this.getSimsunFont(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            String str6 = "本证明一式两份，一份由"+companyName+"保管，一份由结清人保管。";
            Font bottom = new Font(bfChinese, 9, Font.NORMAL);
            Phrase tt6 = new Phrase(str6, bottom);//
            HeaderFooter footer = new HeaderFooter(tt6, false) ;
            footer.setAlignment(1);
            footer.setBorder(Rectangle.NO_BORDER);
            doc.setFooter(footer);
            // 打开文档对象
            doc.open();
            Font FontChinese = new Font(bfChinese, 27, Font.BOLD);
            String str = "结清证明";
            Paragraph tt = new Paragraph(str, FontChinese);
            tt.setLeading(70);
            tt.setAlignment(Element.ALIGN_CENTER);
            doc.add(tt);
            String str1 = "兹有"+custName+"（身份证号码："+certNo+"）于"+DateCustomUtils.getFormatedDate(clearDate,"yyyy年MM月dd日")+"提出"
                    + "提前还款申请。根据其与我司签订合同编号为："+loanNo+"的《个人借款服务合同》及相关文件之约定。确认其满足申请提前还款所需条件，同意其提前还清。";
            String str2 = "现"+custName+"（身份证号："+certNo+"）已于"+DateCustomUtils.getFormatedDate(clearDate,"yyyy年MM月dd日")+"日结清本息及所涉及的其他全部费用。";
            String str3 = "特此证明！";
            Font FontContent = new Font(bfChinese, 13, Font.NORMAL);
            int fistLineIndent = 30; //首行缩进
            int leading = 30; //行间距
            Paragraph tt1 = new Paragraph(str1, FontContent);
            tt1.setFirstLineIndent(fistLineIndent);
            tt1.setLeading(leading);
            tt1.setSpacingBefore(25f);//设置上面空白
            Paragraph tt2 = new Paragraph(str2, FontContent);
            tt2.setFirstLineIndent(fistLineIndent);
            tt2.setLeading(leading);
            Paragraph tt3 = new Paragraph(str3, FontContent);
            tt3.setLeading(leading);
            tt3.setSpacingBefore(50f);//设置上面空白
            doc.add(tt1);
            doc.add(tt2);
            doc.add(tt3);
            if(companyName.contains("柠檬")){
                companyName = companyName;
            }
            else {
                companyName = companyName+"（盖章）";
            }
            String str4 = companyName;
            String str5 = DateCustomUtils.getFormatedDate(clearDate, "yyyy年MM月dd日");
            Paragraph tt4 = new Paragraph(str4, FontContent);
            tt4.setAlignment(Element.ALIGN_RIGHT);
            tt4.setLeading(leading);
            Paragraph tt5 = new Paragraph(str5, FontContent);
            tt5.setFirstLineIndent(280);
            tt5.setLeading(leading);

            doc.add(tt4);
            doc.add(tt5);
            String imageName ="";
            // 加入图片Deepinpl.jpg
            if(companyName.contains("柠檬")){
                imageName ="柠檬.png";
            }else if(companyName.contains("利卡")){
                imageName ="利卡.png";
            }else {
                imageName = "快信.png";
            }
            String path =  Constants.FILE_URL+imageName;
            Image jpg = Image.getInstance(Objects.requireNonNull(path));
            jpg.setAbsolutePosition(320, 360);
            jpg.scaleAbsoluteHeight(150);
            jpg.scaleAbsoluteWidth(150);
            doc.add(jpg);
            doc.newPage();
            // 关闭文档对象，释放资源
            doc.close();
        } catch (DocumentException | IOException e) {
            throw new RuntimeException(e);
        }
    }
    private String getSimsunFont(){
         String path =  Constants.FILE_URL+"simsun.ttc";
        log.info("path value is {} ",path);
        return    path+",1";
    }

}
